<template>
  <div>

    <div class="page-title">
      <span>编辑角色:{{roleName}}</span>
      <a id="back_a"  @click="back()">返回上一页</a>
    </div>

    <div style="margin-bottom: 30px;"></div>
    <el-row :gutter="20">
      <!--菜单权限树-->
      <el-col :span="10">
        <el-card class="box-card">
          <div slot="header">
            <div class="title-box" style="padding-top: 10px; padding-bottom: 13px;">
              <span><el-tag type="success" >菜单</el-tag>&nbsp;</span>
            </div>
            <span class="tips-text">提示：勾选权限即可为角色授权</span>
          </div>
          <el-input class="mgb-15" :placeholder="filterPlaceholderText" v-model="filterMenuPermText"></el-input>
          <el-tree @check-change="saveRoleMenuPerm" show-checkbox ref="menuPermTreeRef" :filter-node-method="filterNode"
                   :data="menuPermissionTree" :props="treeProps" node-key="value" default-expand-all :expand-on-click-node="false">
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>
                <span class="mgl-10">{{ data.name }}</span>
                <span class="mgl-10 tips-text">{{ data.value }}</span>
                <el-tag class="mgl-10" type="success" size="mini">菜单</el-tag>
              </span>
            </span>
          </el-tree>
        </el-card>
      </el-col>

      <!--按钮权限树-->
      <el-col :span="10">
        <el-card class="box-card">
          <div slot="header">
            <div class="title-box" style="padding-top: 10px; padding-bottom: 13px;">
              <span><el-tag type="warning" >按钮</el-tag>&nbsp;权限元数据</span>
            </div>
            <span class="tips-text">提示：勾选权限即可为角色授权</span>
          </div>
          <el-input class="mgb-15" :placeholder="filterPlaceholderText" v-model="filterButtonPermText"></el-input>
          <el-tree ref="buttonPermTreeRef" :filter-node-method="filterNode" :data="buttonPermissionTree"
                   :props="treeProps" node-key="pid" default-expand-all :expand-on-click-node="false">
            <span class="custom-tree-node" slot-scope="{ node, data }">
                <span>
                  <el-checkbox v-if="data.type==permType.BUTTON" v-model="btnCheckboxMap[data.value]"
                               @change="(checked)=>{saveRoleBtnPerm(checked,data.value)}"></el-checkbox>
                  <span class="mgl-10">{{ data.name }}</span>
                  <span class="mgl-10 tips-text">{{ data.value }}</span>
                  <el-tag class="mgl-10" v-if="data.type==permType.MENU" type="success" size="mini">菜单</el-tag>
                  <el-tag class="mgl-10" v-else-if="data.type==permType.BUTTON" type="warning" size="mini">按钮</el-tag>
                </span>
            </span>
          </el-tree>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>

  import tree from '../tree'
  import {parseTime, resetTemp} from '@/utils'
  import { permType, permTypeMap} from '@/utils/constants'
  import {asyncRouterMap} from '@/router' //路由表，定义了菜单和按钮的元数据，可以用来生成权限控制的菜单按钮树
  import debounce from 'lodash/debounce'

  export default {
    name: 'RolePerm',
    data() {
      return {
        permType,
        //当前授权的角色
        roleId: null,
        roleName:'',
        //节点过滤
        filterPlaceholderText: '输入权限名称、权限值过滤',
        filterMenuPermText: '',
        filterButtonPermText: '',
        filterApiPermText: '',
        roleMenuPermUpdateSum: 0,
        roleApiPermUpdateSum: 0,
        //角色的权限值
        roleMenuPvals: [],
        roleBtnPvals:[],
        menuPermissionTree: [],//菜单权限树
        buttonPermissionTree: [],//按钮权限树
        //挂载到按钮权限树的按钮权限数据。由于按钮权限在菜单权限下，key是菜单权限值，value是按钮权限
        btnPermMap:{},
        treeProps: {
          label: 'name',
          children: 'children'
        },
      }
    },

    computed:{
      btnCheckboxMap(){
        let map = {}
        this.roleBtnPvals.forEach(value=>{
          map[value] = true
        });
        return map;
      }
    },
    watch: {
      'filterMenuPermText': debounce(function (val) {
        this.$refs.menuPermTreeRef.filter(val);
      }, 600),
      'filterButtonPermText': debounce(function (val) {
        this.$refs.buttonPermTreeRef.filter(val);
      }, 600)
    },
    created() {
      this.initData()
    },

    methods: {
      //获取后台权限数据
      initData() {
        //获取路由中的角色id
        this.roleId = this.$route.params.roleId;
        //显示菜单权限树
        this.menuPermissionTree = tree.generateMenuPermissionTree()
        //显示按钮权限树
        let menuPermissionTreeCopy = tree.generateMenuPermissionTree()
        this.generateButtonPermissionTree(menuPermissionTreeCopy)
        //加载角色的权限
        this.loadRolePerms()
      },
      /**
       * 加载角色的权限并回显
       */
      loadRolePerms(){
        if(!this.roleId){
          this.$message.error('无法显示角色的权限信息：找不到角色id！');
          return;
        }
        this.$api.loadRolePerms(this.roleId).then(res=>{
            let result = res.data;
            if(result.code ==0){
                let d = result.data;
                if(d.menuList&&d.menuList.length>0){
                    this.roleMenuPvals = d.menuList;
                    this.$refs.menuPermTreeRef.setCheckedKeys(d.menuList);
                }
                //用于回显角色的按钮权限
                this.roleBtnPvals = d.btnList;
                this.roleName = d.roleName;
                this.roleId =   d.roleId;
            }else{
                this.$message.error(result.msg);
            }
        });
      },

      filterNode(value, data) {
        if (!value) return true;
        return data.name.indexOf(value) !== -1 || data.value.indexOf(value) !== -1 ;
      },

      generateButtonPermissionTree(menuPermissionTreeCopy) {
        this.$api.listBtnGroupByParent().then(res=>{
          this.btnPermMap = res.data.data.btnPermMap || {}
          this.buttonPermissionTree = tree.mapToButtonPermissionTree(this.btnPermMap,menuPermissionTreeCopy)
        })
      },

      saveRoleBtnPerm(checked,value){
        let params = {
            roleId: this.roleId,
            value:  value,
            type:   permType.BUTTON
        };
        if(checked){
            this.$api.addRolePerm(params).then((res)=>{
                let result = res.data;
                if(result.code ==0){
                    this.roleBtnPvals.unshift(value);
                    this.$message.success('添加按钮权限成功')
                }else {
                    this.$message.error(result.msg)
                }
          })
        }else{
            this.$api.deleteRolePerm(params).then((res)=>{
                let result = res.data;
                if(result.code ==0){
                    let index = this.roleBtnPvals.findIndex(btnValue=>btnValue==value)
                    this.roleBtnPvals.splice(index,1)
                    this.$message.success('删除按钮权限成功')
                }else{
                    this.$message.error(result.msg)
                }
          })
        }
      },
       // debounce 去抖操作,重新计时。
      saveRoleMenuPerm: debounce(function(){
        this.roleMenuPermUpdateSum++;
        //因为初始化勾选角色的权限会触发一次，但这次的权限数据跟后台是一样的，所以不需要触发更新角色的权限
        if(this.roleMenuPvals.length>0 && this.roleMenuPermUpdateSum==1) {
            return;
        }
        let checkedNodes = this.$refs.menuPermTreeRef.getCheckedNodes();
        let halfCheckedNodes = this.$refs.menuPermTreeRef.getHalfCheckedNodes();
        let values = [...checkedNodes,...halfCheckedNodes].map(perm=>perm.value);
        //发送请求更新角色的权限
        let params = {roleId: this.roleId, type: permType.MENU,values: values };
        this.$api.saveRoleMenuPerm(params).then(res=>{
            if(res.data.code ==0){
                this.$message.success('更新菜单权限成功')
            }else{
                this.$message.error(res.data.msg)
            }
        })
      },500),
     back(){
        this.$router.push({name:'RoleList'});
     }
    }
  }
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  .text {
    font-size: 14px;
  }

  .item {
    margin-bottom: 18px;
  }

  .clearfix:before,
  .clearfix:after {
    display: table;
    content: "";
  }

  .clearfix:after {
    clear: both
  }

  .box-card {
    width: 100%;
  }

  .custom-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }

  .card-title {
    line-height: 50px;
    height: 50px;
  }

  .tips-text {
    font-size: 14px;
    color: #909399;
  }

  .title-box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    span {
      font-size: 22px;
    }
  }

  .update-btn {
    margin-left: 20px;
  }

  .delete-btn {
    margin-left: 20px;
    color: #F56C6C;
  }

  .mgl-10 {
    margin-left: 10px;
  }

  .mgb-15 {
    margin-bottom: 15px;
  }



</style>
